<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Updating selection range to outside of scope of the selection should cause the range removed from the selection</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";

const ArgTypeNodeAndOffset = 0;
const ArgTypeNode = 1;

const rangeMethods = [
  { name: "selectNode", type: ArgTypeNode },
  { name: "selectNodeContents", type: ArgTypeNode },
  { name: "setEnd", type: ArgTypeNodeAndOffset },
  { name: "setEndAfter", type: ArgTypeNode },
  { name: "setEndBefore", type: ArgTypeNode },
  { name: "setStart", type: ArgTypeNodeAndOffset },
  { name: "setStartAfter", type: ArgTypeNode },
  { name: "setStartBefore", type: ArgTypeNode },
];

function execute(range, rangeMethod, node, offset) {
  switch (rangeMethod.type) {
    case ArgTypeNodeAndOffset:
      range[rangeMethod.name](node, offset);
      break;
    case ArgTypeNode:
      range[rangeMethod.name](node);
      break;
    default:
      throw new Error("Unexpected arg type is set");
  }
}

addEventListener("load", () => {
  function selectDiv() {
    getSelection().removeAllRanges();
    const range = document.createRange();
    range.selectNodeContents(document.getElementById("rangeContainer"));
    getSelection().addRange(range);
  }
  function createDocumentFragment() {
    const fragment = document.createDocumentFragment();
    const div = document.createElement("div");
    div.id = "rangeContainer";
    div.innerHTML = "<br>";
    fragment.appendChild(div);
    return fragment;
  }
  for (const rangeMethod of rangeMethods) {
    test(() => {
      selectDiv();
      const fragment = createDocumentFragment();
      execute(
        getSelection().getRangeAt(0),
        rangeMethod,
        fragment.getElementById("rangeContainer"),
        0
      );
      assert_equals(
        getSelection().rangeCount,
        0
      );
    }, `Set selection range into a document fragment with ${rangeMethod.name}`);
    test(() => {
      selectDiv();
      const div = document.querySelector("iframe").contentDocument.getElementById("rangeContainer");
      execute(
        getSelection().getRangeAt(0),
        rangeMethod,
        div,
        0
      );
      assert_equals(
        getSelection().rangeCount,
        0
      );
    }, `Set selection range into a sub-document with ${rangeMethod.name}`);
  }
}, {once: true});
</script>
</head>
<body>
<div id="rangeContainer"><br></div>
<iframe srcdoc="<div id='rangeContainer'><br></div>"></iframe>
</body>
</html>
